home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / unix / utils.1 < prev   
Text File  |  1988-11-02  |  22KB  |  966 lines

  1. Path: xanth!nic.MR.NET!hal!cwjcc!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i040:  unix-utils - UNIX(tm)-like utilities
  5. Message-ID: <10011@swan.ulowell.edu>
  6. Date: 2 Nov 88 20:47:21 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 955
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: brant@uf.msc.umn.edu (Gary Brant)
  12. Posting-number: Volume 2, Issue 40
  13. Archive-name: unix/utils.1
  14.  
  15. Head, tail, tee and wc are similar to *NIX utilities of the same name.
  16. detab and entab remove and instert tabs respectively in source files.
  17. trunc removes trailing white space, inserts left margins,
  18. deletes/converts CR's in source files, etc.
  19.  
  20. [Although the sources are copyrighted, they are freely
  21. redistributable, as mentioned in the readme file.   ..Bob]
  22.  
  23. #    This is a shell archive.
  24. #    Remove everything above and including the cut line.
  25. #    Then run the rest of the file through sh.
  26. #----cut here-----cut here-----cut here-----cut here----#
  27. #!/bin/sh
  28. # shar:    Shell Archiver
  29. #    Run the following text with /bin/sh to create:
  30. #    detab.c
  31. #    entab.c
  32. #    head.c
  33. #    tail.c
  34. #    tee.c
  35. #    trunc.c
  36. #    wc.c
  37. #    readme
  38. # This archive created: Wed Nov  2 15:40:18 1988
  39. cat << \SHAR_EOF > detab.c
  40. /* detab.c - expand tabs to spaces in a file.  If a single tabstop    *
  41.  *    is given, tabs are tabstop spaces apart, otherwise tabstops    *
  42.  *    are at <tab1>, <tab2>,..., <tabn>.  If no file is specified,    *
  43.  *    standard input is read and standard output written.        *
  44.  *                                    *
  45.  * detab [-<tab1> -<tab2>... -<tabn>] [filename... ]            *
  46.  *                                    *
  47.  * detab (C) 1988 by Gary L. Brant                    *
  48.  *                                    *
  49.  * :ts=8                                */
  50.  
  51. #define MAXLINE 1000
  52. #include <stdio.h>
  53. char tabarray[MAXLINE];
  54.  
  55. main (argc, argv)    /* remove trailing blanks and tabs and */
  56.             /* expand tabs in source lines */
  57. int argc;
  58. char *argv[];
  59. {
  60.    int i = 0, j, k, l, ntabs = 0, tabstop = 8;
  61.    int argtabs[99];
  62.    char ch, *pch;
  63.    FILE *ifile, *fopen ();
  64.  
  65.    /* decode tabstop arguments */
  66.    while ((++i < argc) && (argv[i][0] == '-')) {
  67.       j = 1;
  68.       tabstop = 0;
  69.       while ((ch = argv[i][j++]) != '\0') {
  70.      if (ch >= '0' && ch <= '9') {
  71.         tabstop *= 10;
  72.         tabstop += ch - '0';
  73.      } else {
  74.         fputs ("bad args\n", stderr);
  75.         exit (20);
  76.      }
  77.       }
  78.       argtabs[ntabs++] = tabstop;
  79.    }
  80.  
  81.    /* fill tabarray with \1 for each tabstop position */
  82.    for (k = 0; k < MAXLINE; k++)
  83.       tabarray[k] = '\0';
  84.    if (ntabs > 1)
  85.       for (k = 0; k < ntabs; k++)
  86.      if ((l = argtabs[k]-1) < MAXLINE)
  87.         tabarray[l] = '\001';
  88.      else {
  89.         fputs ("bad tab specification\n", stderr);
  90.         exit (20);
  91.      }
  92.    else if ((tabstop > 0) && (tabstop < MAXLINE))
  93.       for (k = tabstop; k < MAXLINE; k += tabstop)
  94.      tabarray[k] = '\001';
  95.    else {
  96.       fputs ("bad tab specification\n", stderr);
  97.       exit (20);
  98.    }
  99.  
  100.    /* remaining arguments should be file names - detab them */
  101.    if (i < argc) {
  102.       while (i < argc)
  103.      if ((ifile = fopen ((pch = argv[i++]), "r")) == NULL) {
  104.         fputs ("detab: cant open ", stderr);
  105.         fputs (pch, stderr);
  106.         putc ('\n', stderr);
  107.         exit (20);
  108.      } else
  109.         detab (ifile);
  110.    } else
  111.       detab (stdin);
  112. }
  113.  
  114.  
  115. /* detab - remove the tabs from one file */
  116.  
  117. detab (ifile)
  118. FILE *ifile;
  119. {
  120.    int n;
  121.    char inline[MAXLINE], outline[MAXLINE], *fgets ();
  122.  
  123.    while ((fgets (inline, MAXLINE, ifile)) != NULL) {
  124.       n = strlen (inline);
  125.       while (--n >= 0)            /* back over white space */
  126.      if (inline[n] != ' ' && inline[n] != '\t' &&
  127.         inline[n] != '\n') break;
  128.       inline[n+1] = '\0';
  129.       expand (inline, outline, MAXLINE);
  130.       puts (outline);
  131.    }
  132. }
  133.  
  134.  
  135. /* expand - expand a line */
  136.  
  137. expand (in, out, lim)
  138. char in[], out[];
  139. int  lim;
  140. {
  141.    register int i, j;
  142.    register char ch;
  143.  
  144.    i = j = 0;
  145.    while (((ch = in[i++]) != '\0') && (j < lim)) {
  146.       if (ch == '\t') {
  147.      register int k;
  148.      register char tc;
  149.  
  150.      k = j;
  151.      out[j++] = ' ';
  152.      while ((j < lim) && ((tc = tabarray[j]) == '\0'))
  153.         out[j++] = ' ';
  154.      if (tc == '\0') {
  155.         j = k;
  156.         out[j++] = ch;
  157.      }
  158.       } else
  159.      out[j++] = ch;
  160.    }
  161.    out[j] = ch;
  162. }
  163.  
  164.  
  165. /* wb_parse is included here only to reduce the size of the executable */
  166.  
  167. void
  168. _wb_parse ()
  169. {
  170. }
  171. SHAR_EOF
  172. cat << \SHAR_EOF > entab.c
  173. /* entab.c - compress spaces to tabs in a file.  If a single tabstop    *
  174.  *    is given, tabs are tabstop spaces apart, otherwise tabstops    *
  175.  *    are at <tab1>, <tab2>,..., <tabn>.  If no file is specified,    *
  176.  *    standard input is read and standard output written.        *
  177.  *                                    *
  178.  * entab [-<tab1> -<tab2> -<tabn>] [filename... ]            *
  179.  *                                    *
  180.  * entab (C) 1988 by Gary L. Brant                    *
  181.  *                                    *
  182.  * :ts=8                                */
  183.  
  184. #define MAXLINE 1000
  185. #include <stdio.h>
  186. char tabarray[MAXLINE];
  187.  
  188. main (argc, argv)    /* remove trailing blanks and tabs and */
  189.             /* compress blanks in source lines */
  190. int argc;
  191. char *argv[];
  192. {
  193.    int i = 0, j, k, l, ntabs = 0, tabstop = 8;
  194.    int argtabs[99];
  195.    char ch, *pch;
  196.    FILE *ifile, *fopen ();
  197.  
  198.    /* decode tabstop arguments */
  199.    while ((++i < argc) && (argv[i][0] == '-')) {
  200.       j = 1;
  201.       tabstop = 0;
  202.       while ((ch = argv[i][j++]) != '\0') {
  203.      if (ch >= '0' && ch <= '9') {
  204.         tabstop *= 10;
  205.         tabstop += ch - '0';
  206.      } else {
  207.         fputs ("bad args\n", stderr);
  208.         exit (20);
  209.      }
  210.       }
  211.       argtabs[ntabs++] = tabstop;
  212.    }
  213.  
  214.    /* fill tabarray with \1 at each tabstop position */
  215.    for (k = 0; k < MAXLINE; k++)
  216.       tabarray[k] = '\0';
  217.    if (ntabs > 1)
  218.       for (k = 0; k < ntabs; k++)
  219.      if ((l = argtabs[k]-1) < MAXLINE)
  220.         tabarray[l] = '\001';
  221.      else {
  222.         fputs ("bad tab specification\n", stderr);
  223.         exit (20);
  224.      }
  225.    else if ((tabstop > 0) && (tabstop < MAXLINE))
  226.       for (k = tabstop; k < MAXLINE; k += tabstop)
  227.      tabarray[k] = '\001';
  228.    else {
  229.       fputs ("bad tab specification\n", stderr);
  230.       exit (20);
  231.    }
  232.  
  233.    /* remaining arguments should be file names - entab them */
  234.    if (i < argc)
  235.       while (i < argc)
  236.      if ((ifile = fopen ((pch = argv[i++]), "r")) == NULL) {
  237.         fputs ("entab: cant open ", stderr);
  238.         fputs (pch, stderr);
  239.         putc ('\n', stderr);
  240.         exit (20);
  241.      } else
  242.         entab (ifile);
  243.    else
  244.       entab (stdin);
  245. }
  246.  
  247.  
  248. /* entab - insert tabs into one file */
  249.  
  250. entab (ifile)
  251. FILE *ifile;
  252. {
  253.    int n;
  254.    char inline[MAXLINE], outline[MAXLINE], *fgets ();
  255.  
  256.    while ((fgets (inline, MAXLINE, ifile)) != NULL) {
  257.       n = strlen (inline);
  258.       while (--n >= 0)            /* back over white space */
  259.      if (inline[n] != ' ' && inline[n] != '\t' && inline[n] != '\n')
  260.         break;
  261.       inline[n+1] = '\0';
  262.       compress (inline, outline, MAXLINE);
  263.       puts (outline);
  264.    }
  265. }
  266.  
  267.  
  268. /* compress - compress one line, replacing strings of blanks with tabs    *
  269.  * to tab stops specified on command line or default            */
  270.  
  271. compress (in, out, lim)
  272. char in[], out[];
  273. int  lim;
  274. {
  275.    register int i = 0, j = 0;
  276.    register char ch;
  277.  
  278.    while (((ch = in[i++]) != '\0') && (i < lim)) {
  279.       if (ch == ' ') {
  280.      register int k = i, tc;
  281.      while (((tc = tabarray[k]) == '\0') && (in[k] == ' ') && (k < lim))
  282.         k++;
  283.      if ((tc == '\001') && (k > i))
  284.         out[j++] = '\t';
  285.      else            /* avoid running through this again next trip */
  286.         while (i++ <= k)
  287.            out[j++] = ch;
  288.      i = k;
  289.       } else if (ch == '\042' || ch == '\047') {
  290.      register int tc;        /* avoid tabbing quoted strings */
  291.      out[j++] = ch;
  292.      while (((tc = in[i++]) != ch) && (i < lim)) {
  293.         if (tc == '\134') {     /* possible protected quote */
  294.            out[j++] = tc;
  295.            tc = in[i++];
  296.            if (i == lim) break;
  297.         }
  298.         out[j++] = tc;
  299.      }
  300.      out[j++] = ch;
  301.       } else
  302.      out[j++] = ch;
  303.    }
  304.    out[j] = ch;
  305. }
  306.  
  307.  
  308. void
  309. _wb_parse ()
  310. {
  311. }
  312. SHAR_EOF
  313. cat << \SHAR_EOF > head.c
  314. /* head.c - print the first few lines in a file.  If count is specified,*
  315.  *    that many lines are printed instead of the default value of    *
  316.  *    ten lines.  If no files are specified, head reads standard    *
  317.  *    input.                                *
  318.  *                                    *
  319.  * head [-<count>] [<file> ...]                     *
  320.  *                                    *
  321.  * head (C) 1988 by Gary L. Brant                    *
  322.  *                                    *
  323.  * :ts=8                                */
  324.  
  325. #include <stdio.h>
  326. #define   MAXLINE   1000
  327.  
  328. void fputs ();
  329. int head = 0;
  330.  
  331. main (argc, argv)    /* list 1st n lines of a file */
  332. int  argc;
  333. char *argv[];
  334. {
  335.    FILE *input, *fopen ();
  336.    void fclose ();
  337.    int default_lines = 10;    /* default number of lines to list */
  338.    int i = 0, j, maxlines;
  339.    char ch;
  340.  
  341.    maxlines = default_lines;
  342.    while (++i < argc) {
  343.       if (argv [i][0] == '-') {     /* remember to bump i in loop */
  344.      maxlines = 0;    /* remember to set maxlines to 0 1st */
  345.      for (j = 1; (ch = argv[i][j]) != '\0'; j++)
  346.         if (ch >= '0' && ch <= '9') {
  347.            maxlines *= 10;
  348.            maxlines += ch - '0';
  349.         } else {
  350.            maxlines = default_lines;
  351.            break;
  352.         }
  353.      default_lines = maxlines;
  354.       } else {
  355.      ++head;
  356.      if ((input = fopen (argv[i], "r")) == NULL) {
  357.         fputs ("head: can't open ", stderr);
  358.         fputs (argv[i], stderr);
  359.         putc ('\n', stderr);
  360.         break;
  361.      } else {
  362.         list (input, argv[i], maxlines);
  363.         fclose (input);
  364.      }
  365.       }
  366.    }
  367.    if (!head)
  368.       list (stdin, "", maxlines);
  369. }
  370.  
  371.  
  372. /* list head of a file */
  373.  
  374. list (fp, fn, maxlines)
  375. FILE *fp;
  376. char *fn;
  377. int maxlines;
  378. {
  379.    int n;
  380.    int i = 0;
  381.    char line[MAXLINE];
  382.    char *fgets ();
  383.  
  384.    while ((i < maxlines) && (fgets (line, MAXLINE, fp)) != NULL) {
  385.       if (i++ == 0)
  386.      heading (fn);
  387.       fputs (line, stdout);
  388.    }
  389. }
  390.  
  391.  
  392. /* heading - print a short heading identifying file */
  393.  
  394. heading (filename)
  395. char *filename;
  396. {
  397.    if (head) {
  398.       fputs ("==> ", stdout);
  399.       fputs (filename, stdout);
  400.       fputs (" <==\n", stdout);
  401.    }
  402. }
  403.  
  404.  
  405. _wb_parse ()
  406. {
  407. }
  408. SHAR_EOF
  409. cat << \SHAR_EOF > tail.c
  410. /* tail.c - print the last few lines in a file.  If count is specified, *
  411.  *    that many lines are printed instead of the default value of    *
  412.  *    ten lines.  If no files are specified, head reads standard    *
  413.  *    input.                                *
  414.  *                                    *
  415.  * tail [-<count>] [<file> ...]                     *
  416.  *                                    *
  417.  * tail (C) 1988 by Gary L. Brant                    *
  418.  *                                    *
  419.  * :ts=8                                */
  420.  
  421. #include <stdio.h>
  422. #define   MAXLINE   1000
  423. void fputs ();
  424. int default_lines = 10; /* default number of lines to list */
  425. int head = 0;
  426.  
  427. main (argc, argv)    /* list 1st n lines of a file */
  428. int  argc;
  429. char *argv[];
  430. {
  431.    FILE *input, *fopen ();
  432.    void fclose ();
  433.    int i = 0, j, maxlines;
  434.    char ch;
  435.  
  436.    maxlines = default_lines;
  437.    while (++i < argc) {
  438.       if (argv [i][0] == '-') {     /* process line count argument */
  439.      maxlines = convert (argv[i]);
  440.      default_lines = maxlines;
  441.      if (maxlines > 4096) {
  442.         fputs ("give me a break!!  n <= 4096!\n", stderr);
  443.         exit (20);
  444.      }
  445.       } else if (argv [i][0] == '+') {
  446.      maxlines = -convert (argv[i]);
  447.      default_lines = maxlines;
  448.       } else {
  449.      ++head;
  450.      if ((input = fopen (argv[i], "r")) == NULL) {
  451.         fputs ("tail: can't open ", stderr);
  452.         fputs (argv[i], stderr);
  453.         putc ('\n', stderr);
  454.         break;
  455.      } else {
  456.         list (input, argv[i], maxlines);
  457.         fclose (input);
  458.      }
  459.       }
  460.    }
  461.    if (!head)
  462.       list (stdin, "", maxlines);
  463. }
  464.  
  465.  
  466. list (fp, fn, maxlines)     /* list tail of a file */
  467. FILE *fp;
  468. char *fn;
  469. int maxlines;
  470. {
  471.    int    i = 0, n, fseek ();
  472.    char line[MAXLINE];
  473.    long cur_pos = 0L, line_pos[4096];
  474.    char *c, *fgets ();
  475.  
  476.    if (maxlines < 0) {        /* +n, head relative list */
  477.       while (maxlines++ < 0 && (c = fgets (line, MAXLINE, fp)) != NULL);
  478.       if (c != NULL) {
  479.      heading (fn);
  480.      while ((fgets (line, MAXLINE, fp)) != NULL)
  481.         fputs (line, stdout);
  482.       }
  483.    } else {            /* -n, tail relative list */
  484.       for (n = 0; n < maxlines; n++)
  485.      line_pos[n] = 0L;
  486.       while ((fgets (line, MAXLINE, fp)) != NULL) {
  487.      n = strlen (line);
  488.      line_pos[i++] = cur_pos;
  489.      cur_pos += n;
  490.      if (i == maxlines)
  491.         i = 0;
  492.       }
  493.       if (cur_pos == 0L)
  494.      return;
  495.       fseek (fp, line_pos[i], 0);
  496.       heading (fn);
  497.       while ((fgets (line, MAXLINE, fp)) != NULL)
  498.      fputs (line, stdout);
  499.    }
  500. }
  501.  
  502.  
  503. heading (filename)
  504. char *filename;
  505. {
  506.    if (head) {
  507.       fputs ("==> ", stdout);
  508.       fputs (filename, stdout);
  509.       fputs (" <==\n", stdout);
  510.    }
  511. }
  512.  
  513.  
  514. convert (string)
  515. char string[];
  516. {
  517.    register int maxlines = 0, j;
  518.    register char ch;
  519.  
  520.    for (j = 1; (ch = string[j]) != '\0'; j++)
  521.    if (ch >= '0' && ch <= '9') {
  522.       maxlines *= 10;
  523.       maxlines += ch - '0';
  524.    } else {
  525.       maxlines = default_lines;
  526.       break;
  527.    }
  528.    return (maxlines);
  529. }
  530.  
  531.  
  532. void _wb_parse ()
  533. {
  534. }
  535. SHAR_EOF
  536. cat << \SHAR_EOF > tee.c
  537. /* tee.c - copy standard input to standard output and one other file.    *
  538.  *    This is useful for splitting (tapping) the pipe.  Presumes you    *
  539.  *    are using a shell program which can pipe the output from one    *
  540.  *    program into the input of another or some other pipe device,    *
  541.  *    but also can be used to make 2 copies of a file.        *
  542.  *                                    *
  543.  * tee <file1 >file2 file3                        *
  544.  * prog1 file1 | tee file3 | prog2 ...                    *
  545.  *                                    *
  546.  * tee (C) 1988 by Gary L. Brant                    *
  547.  *                                    *
  548.  * :ts=8                                */
  549.  
  550. #include <stdio.h>
  551. #include <fcntl.h>
  552. #define MAXLINE 256
  553. #define ERROR    -1
  554.  
  555. void copy ();
  556. int close (), open (), read (), write ();
  557. int err, out2;            /* file handles */
  558.  
  559. main (argc, argv)
  560. int  argc;
  561. char *argv[];
  562. {
  563.  
  564.    err = fileno (stderr);
  565.    if (argc != 2) {
  566.       write (err, "usage: tee <file1 >file2 file3\n", 31);
  567.       exit (20);
  568.    }
  569.  
  570.    /* Manx documentation (lib.35) claims that if O_TRUNC is used, */
  571.    /* then O_CREAT is not needed; HOG_WASH; open() first deletes */
  572.    /* the file & then complains ENOENT (File does not exist!!! */
  573.  
  574.    if ((out2 = open (argv[1], O_WRONLY | O_TRUNC | O_CREAT)) == ERROR) {
  575.       write (err, "tee: cant open ", 15);
  576.       write (err, argv[1], strlen (argv[1]));
  577.       write (err, "\n", 1);
  578.       exit (20);
  579.    }
  580.  
  581.    copy (out2);
  582.    close (out2);
  583. }
  584.  
  585.  
  586. /* copy stdin to stdout and one other file */
  587.  
  588. void copy (out2)
  589. int out2;
  590. {
  591.    int p, in, out1;
  592.    char line[MAXLINE];
  593.  
  594.    in = fileno (stdin);
  595.    out1 = fileno (stdout);
  596.    while ((p = read (in, line, MAXLINE)) > 0) {
  597.       write (out1, line, p);
  598.       write (out2, line, p);
  599.    }
  600. }
  601.  
  602.  
  603. _wb_parse ()
  604. {
  605. }
  606. SHAR_EOF
  607. cat << \SHAR_EOF > trunc.c
  608. /* trunc.c - Remove trailing white space from a file.  In addition    *
  609.  *    perform some simple formatting.  Options include lm (left    *
  610.  *    margin), lc (leftmost column to copy), rc (rightmost column    *
  611.  *    to copy), mc (convert CR's to LF's), and md (delete CR's).      *
  612.  *                                    *
  613.  * trunc [-<mc>|<md>][-lm n][-lc n][-rc n] [<file> ...]         *
  614.  *                                    *
  615.  * trunc (C) 1988 by Gary L. Brant                    *
  616.  *                                    *
  617.  * :ts=8                                */
  618.  
  619. #define MAXLINE 1000
  620. #include <stdio.h>
  621. int lc = 0,        /* leftmost column to copy */
  622.     lm = 0,        /* left margin to insert */
  623.     rc = 0;        /* rightmost column to copy */
  624. int m  = 0;        /* conversion flag for ^M's */
  625. int flag = 0;        /* indicates CR seen and conversion mode on */
  626. int head = 0;
  627. void fputs (), putc ();
  628.  
  629. main (argc, argv)    /*remove trailing blanks and tabs from source lines */
  630. int argc;
  631. char *argv[];
  632.  
  633. {
  634.    int i = 0, j;
  635.    char ch, *pch;
  636.    FILE *ifile, *fopen ();
  637.  
  638.    while ((++i < argc) && (argv[i][0] == '-')) {
  639.       j = 1;
  640.       switch (ch = argv[i][j++]) {
  641.       case 'l': if ((ch = argv[i][j]) == 'c' && i < argc - 1) {
  642.            lc = convert (argv[++i]);
  643.            if (lc > 0)
  644.               lc--;
  645.         } else if (ch = 'm' && i < argc - 1)
  646.            lm = convert (argv[++i]);
  647.         else
  648.            badarg ();
  649.         break;
  650.       case 'm': if ((ch = argv[i][j]) == 'd')
  651.            m = 1;
  652.         else if (ch == 'c')
  653.            m = 2;
  654.         break;
  655.       case 'r': if ((ch = argv[i][j]) == 'c' && i < argc - 1)
  656.            rc = convert (argv[++i]);
  657.         else
  658.            badarg ();
  659.         break;
  660.       default:    badarg ();
  661.         break;
  662.       }
  663.    }
  664.    if (rc == 0)                 rc = MAXLINE - 1 - lm;
  665.    if (lc > rc || rc - lc + lm >= MAXLINE)    badarg ();
  666.  
  667.    while (i < argc) {
  668.       ++head;
  669.       if ((ifile = fopen ((pch = argv[i++]), "r")) == NULL) {
  670.      fputs ("trunc: cant open ", stderr);
  671.      fputs (pch, stderr);
  672.      putc ('\n', stderr);
  673.      exit (20);
  674.       } else
  675.      copy (ifile);
  676.    }
  677.    if (head == 0)
  678.       copy (stdin);
  679. }
  680.  
  681.  
  682. /* copy - copy file, remove trailing white space and format as we go    */
  683. /* inspired by example in: K & R, P. 61                 */
  684.  
  685. copy (ifile)
  686. FILE *ifile;
  687. {
  688.    int irc, n = 0;
  689.    char line[MAXLINE];
  690.  
  691.    irc = rc + lm - lc;
  692.    while (n < lm)
  693.       line[n++] = ' ';
  694.    while ((n = getline (ifile, &line[lm], MAXLINE-1-lm)) > 0) {
  695.       register int in = (lm + n < irc) ? lm + n : irc;
  696.       while (in-- >= lm)
  697.      if (line[in] != ' ' && line[in] != '\t' && line[in] != '\n')
  698.         break;
  699.       if (in < lm) {
  700.      putc ('\n', stdout);
  701.      if (flag) {
  702.         flag = 0;
  703.         putc ('\n', stdout);
  704.      }
  705.       } else {
  706.      if (flag != 0) {
  707.         line[++in] = '\n';
  708.         flag = 0;
  709.      }
  710.      line[++in] = '\n';
  711.      line[++in] = '\0';
  712.      fputs (line, stdout);
  713.       }
  714.    }
  715. }
  716.  
  717.  
  718. /* get line into s, return length
  719.  * inspired by example in: K & R, P. 67     */
  720.  
  721. getline (ifile, s, lim)
  722. FILE *ifile;
  723. char s[];
  724. int  lim;
  725. {
  726.    register int c, i, j;
  727.  
  728.    i = 0;    j = lc;     /* leftmost columns to ignore */
  729.    while (i < lim && (c = getc (ifile)) != EOF && c != '\n') {
  730.       if (c == '\r') {
  731.      if (m == 1)
  732.         continue;
  733.      else if (m == 2) {
  734.         flag = 1;
  735.         continue;
  736.      }
  737.       }
  738.       if (j-- <= 0)
  739.      s[i++] = c;
  740.    }
  741.    if (c  == '\n')
  742.       s[i++] = c;
  743.    s[i] = '\0';
  744.    return (i);
  745. }
  746.  
  747.  
  748. /* convert - convert numeric command-line arguments to binary    *
  749.  * returns -1 if non-numeric data encountered            */
  750.  
  751. convert (argv)
  752. char *argv;
  753. {
  754.    register long i = 0;
  755.    register char ch;
  756.    register int j=0;
  757.  
  758.    while ((ch = argv[j++]) != '\0')
  759.       if (ch >= '0' && ch <= '9') {
  760.      i *= 10;
  761.      i += ch - '0';
  762.       } else
  763.      return (-1);
  764.    return (i);
  765. }
  766.  
  767.  
  768. /* badarg - complain about bad argument */
  769.  
  770. badarg ()
  771. {
  772.      fputs ("bad args\n", stderr);
  773.      exit (20);
  774. }
  775.  
  776.  
  777. _wb_parse ()
  778. {
  779. }
  780. SHAR_EOF
  781. cat << \SHAR_EOF > wc.c
  782. /* wc.c - count the number of lines, words, and characters in a file.    *
  783.  *                                    *
  784.  * wc [<file> ...]                            *
  785.  *                                    *
  786.  * wc (C) 1988 by Gary L. Brant                     *
  787.  *                                    *
  788.  * :ts=8                                */
  789.  
  790. #include <stdio.h>
  791. #define     FALSE        0
  792. #define     TRUE        1
  793. #define     COUNT_LINES    4
  794. #define     COUNT_WORDS    2
  795. #define     COUNT_CHARS    1
  796. int cur_flag, def_flag = COUNT_LINES | COUNT_WORDS | COUNT_CHARS;
  797. int head;
  798. long  lines, words, chars;
  799. long  tlines=0, twords=0, tchars=0;
  800. char string[] = "         ";
  801.  
  802. main (argc, argv)    /* count lines, words, chars in input */
  803. int  argc;
  804. char *argv[];
  805. {
  806.    register int i = 0, j;
  807.    register char ch;
  808.    FILE *input, *fopen ();
  809.    void fclose ();
  810.  
  811.    cur_flag = def_flag;
  812.    while (++i < argc) {
  813.       if (argv [i][0] == '-') {     /* remember to bump i in loop */
  814.      def_flag = cur_flag;
  815.      cur_flag = 0;
  816.      for (j = 1; (ch = argv[i][j]) != '\0'; j++)
  817.         switch (ch) {
  818.         case 'l':
  819.         cur_flag |= COUNT_LINES;
  820.         break;
  821.         case 'w':
  822.         cur_flag |= COUNT_WORDS;
  823.         break;
  824.         case 'c':
  825.         cur_flag |= COUNT_CHARS;
  826.         break;
  827.         default:
  828.         cur_flag = def_flag;
  829.         }
  830.       } else {
  831.      ++head;
  832.      if ((input = fopen (argv[i], "r")) == NULL) {
  833.         fputs ("wc: can't open ", stderr);
  834.         fputs (argv[i], stderr);
  835.         putc ('\n', stderr);
  836.         continue;
  837.      } else {
  838.         wc (input, argv[i]);
  839.         fclose (input);
  840.      }
  841.       }
  842.    }
  843.    if (!head)
  844.       wc (stdin, "");
  845.    else if ( head > 1)
  846.       print (tlines, twords, tchars, "total");
  847. }
  848.  
  849.  
  850. /* count words, etc. in 1 file
  851.  * inspired by example from: K.&R. P. 18    */
  852.  
  853. wc (fp, fn)
  854. FILE *fp;
  855. char *fn;
  856. {
  857.    register int in, c;
  858.  
  859.    in = FALSE;
  860.    lines = words = chars = 0;
  861.    while ((c = getc (fp)) != EOF) {
  862.       ++chars;
  863.       if (c == '\n') {
  864.      ++lines;
  865.      in = FALSE;
  866.       } else if (c == ' ' || c == '\t')
  867.      in = FALSE;
  868.       else if (!in) {
  869.      in = TRUE;
  870.      ++words;
  871.       }
  872.    }
  873.    print (lines, words, chars, fn);
  874.    tlines += lines;
  875.    twords += words;
  876.    tchars += chars;
  877. }
  878.  
  879.  
  880. /* print - print counts for a file */
  881.  
  882. print (lines, words, chars, fn)
  883. long lines, words, chars;
  884. char *fn;
  885. {
  886.    if (cur_flag & COUNT_LINES) {
  887.       convert (lines, string);
  888.       fputs (string, stdout);
  889.    }
  890.    if (cur_flag & COUNT_WORDS) {
  891.       convert (words, string);
  892.       fputs (string, stdout);
  893.    }
  894.    if (cur_flag & COUNT_CHARS) {
  895.       convert (chars, string);
  896.       fputs (string, stdout);
  897.    }
  898.    if (head)
  899.       fputs (fn, stdout);
  900.    putc ('\n', stdout);
  901. }
  902.  
  903.  
  904. convert (val, string)
  905. register long val;
  906. register char *string;
  907. {
  908.    register int i = 7;
  909.  
  910.    if (val == 0)
  911.       string[i--] = '0';
  912.    while (val != 0) {
  913.       register long j, k;
  914.       j = val / 10;
  915.       k = val - 10 * j;
  916.       val = j;
  917.       string[i--] = '0' + k;
  918.       if (i < 0)
  919.      break;
  920.    }
  921.    while (i >= 0)
  922.       string[i--] = ' ';
  923. }
  924.  
  925.  
  926. _wb_parse ()
  927. {
  928. }
  929. SHAR_EOF
  930. cat << \SHAR_EOF > readme
  931. Here are some utilities that I have found useful.  head, tail, tee 
  932. and wc are similar to *NIX utilities of the same name.  detab and
  933. entab remove and instert tabs respectively in source files.  trunc
  934. removes trailing white space, inserts left margins, deletes/converts
  935. CR's in source files, etc.  
  936.  
  937. All of these utilities write to standard output and read from 
  938. standard input if a file name is not provided on the command line.
  939. This is so that each may 'pipe' its output to the input of another.
  940. Note that if someday *real* pipes become available (:-)), tail will 
  941. break due to seeks.
  942.  
  943. These programs were compiled using the Manx C compiler (v3.6a), but 
  944. conversion to Lattice should be easy; I have tried to keep all of 
  945. the code as straight-forward as possible.
  946.  
  947. The sources & binaries are freely distributable;  you may do anything
  948. you like with them except sell them for profit as long as you leave
  949. my name in the source and include this notice with the source files.
  950.  
  951. Have fun.
  952.  
  953.  
  954.          Gary Brant
  955.  
  956.     US mail: 1355 Eustis St. #1
  957.              St. Paul, MN 55108
  958.  
  959.     ARPA:     brant@uc.msc.umn.edu
  960. SHAR_EOF
  961. #    End of shell archive
  962. exit 0
  963. -- 
  964. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  965. Have five nice days.
  966.